[#ftl]
[@define "agile._ContainerSelectorMixin"]
	adviseMoveable:function(){
		return this.metadata("moveable");
	}
	,init:function(){		
		if(!this.hasSelector || this._initContainerSelectorMixin){
			 return;
		}
		this._initContainerSelectorMixin = true;
		
//		console.log(this.declaredClass,"[agile._ContainerSelectorMixin]initSelector");
		this.agileSelector = construct.create("div",{innerHTML:""});
		
		domClass.add(this.agileSelector,"agileSelector");

		var containerNode= this.getContainerNode();
		construct.place(this.agileSelector,containerNode,1);
		this.own(
		on(containerNode,"mousedown",lang.hitch(this,function(event){			
			//20150522:selection mode is enabled when the widget is not movable
			if(this.adviseMoveable()) return;
			
//			console.log(this.declaredClass,"[agile._ContainerSelectorMixin]onmousedown",event.target !== containerNode,event.target,containerNode);
						
//			if(event.target !== containerNode) return;
			if(!this._moveWithinSelector){
				this.mouseDown(event);
				this._selectorMouseDown = true;			
				style.set(this.domNode,{cursor:"crosshair"});
			}
		}))

		,on(containerNode,"mousemove",lang.hitch(this,function(event){
			//20150522:selection mode is enabled when the widget is not movable
			if(this.adviseMoveable()) return;
			
//			if(this._moveWithinSelector){
//				//this.agileSelector.startPosition = this.getLeftTop(event);
//				console.log("@@@@ switch move context to container node",this.getLeftTop(event))
//			}
			this._moveWithinSelector = false;
			
//			console.log(this.declaredClass,"[agile._ContainerSelectorMixin]onmousemove:",event.target !== containerNode,event.target,containerNode);
//			if(event.target !== containerNode) return;
			if(!this._moveWithinSelector){
				if(this._selectorMouseDown){
					this.mouseMove(event);
				}
			}
		}))

		,on(containerNode,"mouseup",lang.hitch(this,function(event){
			//20150522:selection mode is enabled when the widget is not movable
			if(this.adviseMoveable()) return;
			//fixme:TODO this block should be executed once rather than twice
//			console.log(this.declaredClass,"[agile._ContainerSelectorMixin]onmouseup",event.target,event.target !== containerNode,this._selectorMouseDown);
//			if(event.target !== containerNode) return;
			if(!this._moveWithinSelector){
				if(this._selectorMouseDown){
					this.mouseUp(event);
					this._selectorMouseDown = false;				
				}
				style.set(this.domNode,{cursor:"default"});	
			}
//			event.stopPropagation();
		}))
		
		,on(this.agileSelector,"mousemove",lang.hitch(this,function(event){
			//first time move within selector
//			if(!this._moveWithinSelector){
//				//this.agileSelector.startPosition = this.getLeftTop(event);
//				console.log("### switch move context to selector node",this.getLeftTop(event),",startPosition=",this.agileSelector.startPosition);				
//			}
			this._moveWithinSelector = true;			
			this.mouseMove(event);
			event.stopPropagation();			
		}))
		
		,on(this.agileSelector,"mouseup",lang.hitch(this,function(event){
			this.mouseUp(event);	
			event.stopPropagation();
			style.set(this.domNode,{cursor:"default"});			
			this._moveWithinSelector = false;
		}))
		);
	}	
	,mouseDown:function(event){		
//		//console.log("leftMouse:",mouse.isLeft(event),"rightMouse:",mouse.isRight(event));
		if(mouse.isLeft(event)){//left mouse click
			this.agileSelector.startPosition = this.getLeftTop(event);
			style.set(this.agileSelector,{display:"block",left:this.agileSelector.startPosition.left+"px", top:this.agileSelector.startPosition.top+"px",width:"0px",height:"0px"});
			
//			//console.log("##########agileSelector=",this.agileSelector);
		}else if(mouse.isRight(event)){//right mouse click
			var offset = this.getOffset(event);			
			topic.publish("agile.widget.selectedTarget",this,offset);
		}
	}
	,mouseMove:function(event){		
//		//console.log("@@@@@@@@@@@@startPosition=",this.agileSelector.startPosition);
		if(this.agileSelector.startPosition != null){		
			var currentPosition = this.getLeftTop(event);
			var w =4;
			var h =4;			
			var width = currentPosition.left - this.agileSelector.startPosition.left;
			var height = currentPosition.top - this.agileSelector.startPosition.top;
			if(this._moveWithinSelector){
				width = currentPosition.left;
				height = currentPosition.top;
			}
//			console.log("@@@@@@@@@@width=",width,",height=",height,",currentPosition=",currentPosition,",startPosition=",this.agileSelector.startPosition);
			if(width > 0 && height > 0){
				style.set(this.agileSelector,{
						left:(this.agileSelector.startPosition.left)+"px"
						,top:(this.agileSelector.startPosition.top)+"px"
						,width:(width - w)+"px"
						,height:(height - h)+"px"
						});
			}else if(width > 0 && height < 0){
				style.set(this.agileSelector,{
						left:(this.agileSelector.startPosition.left)+"px"
						,top:(this.agileSelector.startPosition.top + height + h)+"px"
						,width:(width - w)+"px"
						,height:(-height -h)+"px"
						});
			}
			else if(width < 0 && height < 0){
				style.set(this.agileSelector,{
						left:(this.agileSelector.startPosition.left + width + w)+"px"
						,top:(this.agileSelector.startPosition.top + height + h)+"px"
						,width:(-width-w)+"px"
						,height:(-height-h)+"px"
						});
			}else if(width < 0 && height > 0){
				style.set(this.agileSelector,{
						left:(this.agileSelector.startPosition.left + width + w)+"px"
						,top:(this.agileSelector.startPosition.top)+"px"
						,width:(-width -w)+"px"
						,height:(height-h)+"px"
						});
			}else{
				style.set(this.agileSelector,{
					left:(this.agileSelector.startPosition.left)+"px"
					,top:(this.agileSelector.startPosition.top)+"px"
					,width: width +"px"
					,height: height +"px"
					});
			}
			this._eagerSelect = (width < 0 || height < 0);
		}
	}
	,mouseUp:function(event){
		//console.log(this.declaredClass,"###mouseUp=");
		
		if(mouse.isLeft(event)){//left mouse click
			//de-select existing selected widgets
          array.forEach(this.getSelectedChildren(),function(child){
	          child.onDeselected();
	      });
			
			var selectionRange = agile.calcSize(this.agileSelector);
//			console.log(this.declaredClass,"###selectionRange=",selectionRange);
            this._singleSelect = false;//flag in the Container to allow multiple selection
			var widgets = [];
			if(this._eagerSelect){
				array.forEach(this._getChildren(),function(child){
					if(
						(//left-top
						child.dimension["left"] > selectionRange.l 
						&& child.dimension["top"] > selectionRange.t
						&& child.dimension["left"] - selectionRange.l < selectionRange.w
						&& child.dimension["top"] - selectionRange.t < selectionRange.h
						)
						|| (//right-top
						child.dimension["left"] + child.dimension["width"] > selectionRange.l 
						&& child.dimension["top"] > selectionRange.t
						&& child.dimension["left"]  + child.dimension["width"] - selectionRange.l < selectionRange.w
						&& child.dimension["top"] - selectionRange.t < selectionRange.h
						)
						||(	//bottom-left
						child.dimension["left"] > selectionRange.l 
						&& child.dimension["top"]  + child.dimension["height"] > selectionRange.t
						&& child.dimension["left"] - selectionRange.l < selectionRange.w
						&& child.dimension["top"] + child.dimension["height"] - selectionRange.t < selectionRange.h
						)
						||(//bottom-right
						child.dimension["left"] + child.dimension["width"] > selectionRange.l 
						&& child.dimension["top"]  + child.dimension["height"] > selectionRange.t
						&& child.dimension["left"]  + child.dimension["width"] - selectionRange.l < selectionRange.w
						&& child.dimension["top"] + child.dimension["height"] - selectionRange.t < selectionRange.h
						)
					){
						widgets.push(child);
						child.onSelected();
					}
				});
			}else{
				array.forEach(this._getChildren(),function(child){				 
					if(child.dimension["left"] > selectionRange.l 
							&& child.dimension["top"] > selectionRange.t
							&& (child.dimension["left"] + child.dimension["width"] < selectionRange.l + selectionRange.w)
							&& (child.dimension["top"] + child.dimension["height"] < selectionRange.t + selectionRange.h)
					){						
						widgets.push(child);
						child.onSelected();
					}
				});
			}	
			this._singleSelect = true;
//			console.log(this.declaredClass,"###widgets=",widgets);
			//single select
			if(widgets.length == 1){
				topic.publish("agile.widget.selected",widgets[0]);
			}else if(widgets.length == 0){				
				topic.publish("agile.page.selected",null);			
			}else{
				topic.publish("agile.widget.selected",null);
			}
			
			this.agileSelector.startPosition = null;
			style.set(this.agileSelector,{width:"0px",height:"0px",display:"none"});
			
//			//console.log("selectedWidgets",selectedWidgets);
		}else if(mouse.isRight(event)){//right mouse click
//			//console.log("onmouseup","right mouse up");
		}		
	}
	,getLeftTop:function(event){
		var offset = this.getOffset(event);			
		var anchor = this.metadata("anchor");
		var leftTop = offset;
		if(anchor){
			leftTop = {left: offset.left + anchor.left,top: offset.top + anchor.top};
		}		
//		//console.log(this.declaredClass,"offset=",offset.left,offset.top,"anchor=",anchor.left,anchor.top);
		return leftTop;
	}
	,getOffset:function(event){
//		//console.log("event.offsetX",event.offsetX);
		if(event.offsetX == undefined){
			var containerBox = agile.coords(event.target,true);
			event.offsetX = event.clientX - containerBox.x;
			event.offsetY = event.clientY - containerBox.y;
		}
		return {left:event.offsetX,top:event.offsetY};
	}
[/@] 